#ifndef __ICHARACTER_H__
#define __ICHARACTER_H__

#include <Game.h>

using namespace std;

typedef struct Keystroke
{
	char ch;
	unsigned int timestamp;
} Keystroke_t;


class ICharacter
{
	/*
	TODO:
		isDying()
		isDead()
	*/
	
	protected:
		int mHealth;
		float mSpeed;
		float mX;
		float mY;
		float mZ;
		float mAttackRange;
		float mLastTime;
		float mTimeUntilIdle;
		
		//The game class this belongs to
		Game* mGame;
		
		//Player states
		bool mIsPunching;
		bool mIsMoving;
		bool mIsKicking;
		bool mIsAttacking;
		
	public:
		//Object Management
		ICharacter();
		virtual ~ICharacter() = 0;
		
		//Movement
		bool moveForward(); //Returns true if character could move forward
		bool moveBackward(); //Returns true if character could move backward...
		bool moveLeft();
		bool moveRight();
		
		//Attacks
		void punch();
		void kick();
		
		//Accessors
		int getHealth();
		
		//Modifiers
		void setHealth(int h);
		void setGame(Game* g);
		void setX(float x);
		void setY(float y);
		void setZ(float z);
		void setPosition(float x, float y, float z);
		
		//Misc.
		
		/*
		The update method will be called every frame (via OGRE)
		It will allow the character to receive input for what to do
		from the user, or use pre-defined NPC movement
		*/
		
		virtual void update(float elapsed);
		bool isInRangeOf(ICharacter* c);
		bool isPunching();
		bool isKicking();
		bool isMoving();
		bool isDead();
		bool isAttacking();
		void die();
};

class NonPlayerCharacter : public ICharacter
{
	public:
		NonPlayerCharacter();
		virtual ~NonPlayerCharacter();
		void update(float elapsed);
};

class PlayerCharacter : public ICharacter
{
	private:
		list<Keystroke_t*>* mKeystrokes;
		void checkForCombos();
		int mLastMatchedBeatObject;
		float mMultiplier;
		float mTimeUntilIdle;
		Command_t* mPerformedCommand;
		
	public:
		//TODO: Make this take in health and other paramters
		PlayerCharacter();
		virtual ~PlayerCharacter();
		void clearKeyBuffer();
		string getKeyBuffer();
		void update(float elapsed);
		void pressed(char ch, unsigned int timestamp);
		void punch();
		void kick();
};


#endif
